<?php if (!defined('ITPK')) exit('You can not directly access the file.');

/**
 * Webqq操作类
 * @author 冬天的秘密
 * @link http://bbs.itpk.cn
 * @version 1.0
 */

class WebRobot {

	public $uin;
	public $qqPer;
	public $runlogPer;
	public $groupmemberPer;
	public $verificationPer;
	public $cookiePer;
	public $pluginPer;

	public function __construct( $uin, $qqPer, $runlogPer, $groupmemberPer, $verificationPer, $cookiePer, $pluginPer ) {
		$this->uin = $uin;
		$this->qqPer = $qqPer;
		$this->runlogPer = $runlogPer;
		$this->groupmemberPer = $groupmemberPer;
		$this->verificationPer = $verificationPer;
		$this->cookiePer = $cookiePer;
		$this->pluginPer = $pluginPer;
	}

	public function checkVerify() {
		$check = WqCommon::web_curl(WqCommon::getCheckRequest($this->uin));
		$arr = WqCommon::pregs($check, 'checkvc');
		if (array_key_exists(0, $arr) && $arr[0] == 0) {
			$this->runlogPer->insertMe($this->uin, "不需要验证码");
			$carr = WqCommon::pregs($check, 'cookie');
			$cookie = WqCommon::cookies($carr);
			$verifysession = $arr[3];
			$status = StatusUtil::LOADING_RSA;
			$this->qqPer->updateProfileToString($this->uin, "code", trim($arr[1]));
		} else {
			$this->runlogPer->insertMe($this->uin, "需要验证码");
			$get = $check = WqCommon::web_curl(WqCommon::getImageRequest($this->uin, $arr[1]));;
			$arr = WqCommon::pregs($get, 'cookie');
			$verifysession = str_replace(array('verifysession='), array(''), $arr[0]);
			$cookie = trim($arr[0]);
			$code = WqCommon::pregs($get, 'code');
			$verifysession = trim($verifysession);
			$this->verificationPer->replaceMe($this->uin, addslashes($code));
			$status = StatusUtil::LOADING_VERIFY;
		}
		$this->qqPer->updateProfileToInt($this->uin, "status", $status);
		$this->qqPer->updateProfileToString($this->uin, "verifysession", $verifysession);
		$this->qqPer->updateProfileToString($this->uin, "cookie", $cookie);
		return $status;
	}

	public function login( $qq, $status ) {
		$get = WqCommon::web_curl(WqCommon::getFirstLoginRequest($qq['uin'], $qq['rsa_pass'], $qq['code'], $qq['verifysession']), $qq['cookie']);
		$arr = WqCommon::pregs($get, 'cookie');
		$cookie = WqCommon::cookies($arr);
		$cookiearr = WqCommon::cookies($arr, 1);
		$ptwebqq = $cookiearr['ptwebqq'];
		$arr = WqCommon::pregs($get, 'login1');
		$is_succes = false;
		if (array_key_exists(1, $arr) && $arr[1] == 0) {
			$this->runlogPer->insertMe($this->uin, "第一次登录成功");
			$get = WqCommon::web_curl(WqCommon::getOtherRequest($arr[3]), $cookie);
			$arr = WqCommon::pregs($get, 'cookie');
			$cookie = WqCommon::cookies($arr);
			$cookiearr = WqCommon::cookies($arr, 1, $cookiearr);
			$clientid = '5' . rand(100000, 999999);
			$get = WqCommon::web_curl(WqCommon::getSecondLoginRequest($ptwebqq, $clientid), $cookie, false);
			$arr = json_decode($get, true);
			if (array_key_exists('retcode', $arr) && $arr['retcode'] == 0) {
				$this->runlogPer->insertMe($this->uin, "第二次登录成功");
				$this->cookiePer->replaceMe($this->uin, WqCommon::arrcookie($cookiearr), $ptwebqq, $arr['result']['vfwebqq'], $arr['result']['psessionid'], $clientid);
				$status = StatusUtil::ONLINE;
				$this->qqPer->updateProfileToInt($this->uin, "status", $status);
				$this->qqPer->updateProfileToString($this->uin, "cookie", $cookie);
				$is_succes = true;
			} elseif (array_key_exists('retcode', $arr)) {
				$this->runlogPer->insertMe($qq['uin'], "第二次登录失败，错误信息:" . $arr['retcode'] . $arr['errmsg']);
			} else {
				$this->runlogPer->insertMe($qq['uin'], '第二次登录链接失败');
			}
		} elseif (array_key_exists(1, $arr)) {
			$this->runlogPer->insertMe($qq['uin'], "第一次登录失败，原因:" . $arr[5]);
		} else {
			$this->runlogPer->insertMe($qq['uin'], "第一次登录链接失败");
		}
		$this->qqPer->removeLoginRecord($this->uin);
		if (!$is_succes) {
			$this->qqPer->updateProfileToInt($this->uin, "status", StatusUtil::INIT);
		}
		return $status;
	}

	public function run( $start_time ) {
		$rows = $this->cookiePer->getMeByUin($this->uin);
		if (!$rows) {
			$this->runlogPer->insertMe($this->uin, 'Cookie丢失，已经自动关闭运行，请重新登录');
			$this->qqPer->updateProfileToInt($this->uin, "status", StatusUtil::INIT);
			$this->qqPer->updateProfileToInt($this->uin, "is_run", 0);
		}
		$cookie = trim($rows['cookie']);
		$ptwebqq = trim($rows['ptwebqq']);
		$vfwebqq = trim($rows['vfwebqq']);
		$psessionid = trim($rows['psessionid']);
		$clientid = trim($rows['clientid']);
		$now_time = time();
		while ($now_time - $start_time < 60) {
			$get = WqCommon::web_curl(WqCommon::getPollRequest($ptwebqq, $clientid, $psessionid), $cookie, false);
			$arr = json_decode($get, true);
			if (@array_key_exists('retcode', $arr) && $arr['retcode'] == 0) {
				$this->runlogPer->insertMe($this->uin, '收到新消息');
				$this->process_message($arr, $rows);
			} elseif (@array_key_exists('retcode', $arr) && ($arr['retcode'] == 103 || $arr['retcode'] == 121)) {
				$this->runlogPer->insertMe($this->uin, '请检查账号是否被封');
				$this->qqPer->updateProfileToInt($this->uin, "status", StatusUtil::INIT);
				$this->qqPer->updateProfileToInt($this->uin, "is_run", 0);
				break;
			} elseif (@array_key_exists('retcode', $arr) && $arr['retcode'] != 116) {
				if ($arr['errmsg'] != "") {
					$this->runlogPer->insertMe($this->uin, $arr['retcode'].$arr['errmsg']);
					$this->qqPer->updateProfileToInt($this->uin, "status", StatusUtil::INIT);
					$this->qqPer->updateProfileToInt($this->uin, "is_run", 0);
					break;
				}
			} else {
				$this->runlogPer->insertMe($this->uin, "暂无消息");
			}
			$now_time = time();
		}
	}

	/**
	 * 简单的预处理下接收到的消息，主要是对QQ表情的处理
	 * @param array $contentArray
	 * @return string
	 */
	public function dealMsgArray($contentArray) {
		$msg = "";
		for ($k = 1; $k < count($contentArray); $k++) {
			if (trim($contentArray[$k]) == "") {
				if ($contentArray[$k][1] != "") {
					$msg = "[face".$contentArray[$k][1]."end]";
					break;
				}
				continue;
			}
			$msg .= (' ' . $contentArray[$k]);
		}
		return trim($msg);
	}

	public function chuliMsg($msg) {
		$msg = preg_replace("/\r\n/is", "%5C%5Cn", $msg);
		if (count(explode("[face", $msg)) > 1) {
			$msg = preg_replace('/\[face(\d{1,3})end\]/is', '%5C%22%2C%5B%5C%22face%5C%22%2C\\1%5D%2C%5C%22', $msg);
		}
		return $msg;
	}

	/**
	 * 处理机器人收到的消息，并进行分类处理
	 * @param array $arr
	 */
	public function process_message($arr, $rows) {
		foreach ($arr['result'] as $news) {
			if ($news['poll_type'] == 'message' && ($news['value']['msg_type'] == 9 || $news['value']['msg_type'] == 10)) {
				$this->personalMsg($news, $rows);	//个人消息
			} elseif ($news['poll_type'] == 'group_message') {
				$this->groupMsg($news, $rows);		//群消息
			} elseif ($news['poll_type'] == 'sys_g_msg') {
				$this->sysGroupMsg($news, $rows);	//加群验证消息
			}
		}
	}

	public function groupMsg($news, $rows) {
		$is_reply = $this->qqPer->getIsReplyByUin($this->uin);
		if ($is_reply == 1) {
			$reply = false;
			$contentArray = $news['value']['content'];
			$msg = $this->dealMsgArray($contentArray);
			$group_uin = $news['value']['info_seq'];
			$send_uin = $news['value']['send_uin'];
			$from_uin = $news['value']['from_uin'];
			$member_uin = WqCommon::getFriendUinBySendUin($send_uin, $rows);
			$webGroup = $this->setGroupMember($rows, $group_uin, $member_uin, $send_uin);
			$plugin_id = $webGroup['plugin_id'];
			//开启了监控所有消息并启用状态的插件
			$plugins1 = $this->pluginPer->getMe(1, 1);
			if ($plugins1) {
				foreach ($plugins1 as $plugin) {
					$reply = $this->runPluginMain($plugin['class_name'], $msg, $webGroup);
				}
			}
			if (!$reply) {
				//未开启监控所有消息并启用状态的插件
				$plugins2 = $this->pluginPer->getMe(1, 0);
				/**
				 * 如果有开启的插件，则进入判断
				*/
				if ($plugins2) {
					foreach ($plugins2 as $plugin) {
						if ($plugin_id != 0 && $plugin_id != $plugin['id']) {
							continue;
						}
						if ($plugin_id == 0) {
							$instruction = explode(PART, $plugin['instruction']);
							$instruction_type = $plugin['instruction_type'];
							if (($instruction_type == InstructionUtil::EQUAL && !DataUtil::is_equal($instruction, $msg, true))
								|| ($instruction_type == InstructionUtil::START_CONTAIN && !DataUtil::start_contain($instruction, $msg, true))
								|| ($instruction_type == InstructionUtil::END_CONTAIN && !DataUtil::end_contain($instruction, $msg, true))
								|| ($instruction_type == InstructionUtil::IS_CONTAIN && !DataUtil::is_contain($instruction, $msg, true)))
							{
								continue;
							}
						}
						if ($plugin_id != $plugin['id']) {
							$this->groupmemberPer->updatePluginId($webGroup['id'], $plugin['id']);
						}
						$reply = $this->runPluginMain($plugin['class_name'], $msg, $webGroup);
						break;
					}
				}
			}
			/**
			 * 如果$reply为false则调用茉莉机器人插件回复群成员的回答
			 */
			if (!$reply) $reply = $this->runPluginMain("WebapiHandler", $msg, $webGroup);

			$rj = json_decode($reply);
			$content = "";
			$number = 0;
			if ($rj) {
				$content = $rj->content;
				$number = $rj->number;
			}
			$number = $number > 3 ? 3 : $number;
			if ($number > 0 && !DataUtil::is_empty($content)) {
				for ($i = 0; $i < $number; $i++) {
					$this->send_group_msg($rows, $group_uin, $from_uin, $content);
				}
			}
		}
	}

	/**
	 * 回复私人消息（为了机器人安全起见，只回复机器人创建者QQ的私聊消息）
	 */
	public function personalMsg($news, $rows) {
		$from_uin = $news['value']['from_uin'];
		$send_uin = WqCommon::getFriendUinBySendUin($from_uin, $rows);
		$create_uin = $this->qqPer->getCreateUinByUin($this->uin);
		//判断消息发送者是否为机器人创建者QQ，如果是的话就进行回复
		if ($send_uin == $create_uin) {
			$contentArray = $news['value']['content'];
			$msg = $this->dealMsgArray($contentArray);
			$this->runlogPer->insertMe($this->uin, "收到私人（{$send_uin}）消息:{$msg}");
			$reply = @$this->runPluginMain("WebapiHandler", $msg, null);
			$rj = json_decode($reply);
			$content = "";
			if ($rj) {
				$content = $rj->content;
			}
			if (!DataUtil::is_empty($content)) {
				$this->sendmg($rows, $from_uin, $content, false);
			}
		}
	}

	/**
	 * 自动同意加群
	 */
	public function sysGroupMsg($news, $rows) {
		if ($news['value']['type'] == 'group_request_join') {
			$from_uin = $news['value']['from_uin'];
			$to_uin = $news['value']['to_uin'];
			$request_uin = $news['value']['request_uin'];
			$ver_msg = $news['value']['msg'];
			$type = $news['value']['type'];
			$gcode = $news['value']['gcode'];
			$nick = WqCommon::getUinVerProfile($request_uin, $type, $from_uin, $rows);
			$qunm = WqCommon::getQunVerProfile($gcode, $rows);
			$is_auto_group = $this->qqPer->getIsAutoGroupByUin($this->uin);
			if ($is_auto_group) {
				WqCommon::setNewFriends($from_uin, $request_uin, $gcode, $rows);
				$name = $this->qqPer->getProfileByUin($this->uin, "name");
				$reply = $nick . "申请加入" . $qunm . UCR;
				$reply .= "验证消息：" . $ver_msg . UCR;
				$reply .= FaceUtil::get(12) . $name . "已经同意" . UCR . UCR;
				$reply .= FaceUtil::get(33) . "欢迎" . $nick . "加入" . $qunm . FaceUtil::get(33);
				$this->sendmg($rows, $news['value']['from_uin'], $reply);
			} else {
				$reply = $nick . "申请加入" . $qunm . UCR . "验证消息：" . $ver_msg;
				$this->sendmg($rows, $news['value']['from_uin'], $reply);
			}
			$this->runlogPer->insertMe($this->uin, "{$nick}申请加入{$qunm}");
		}
	}

	/**
	 * 发送群消息
	 */
	public function send_group_msg($rows, $group_uin, $from_uin, $reply) {
		$this->sendmg($rows, $from_uin, $reply);
	}

	/**
	 * 发送消息
	 */
	public function sendmg($rows, $from_uin, $reply, $is_group_msg = true) {
		$reply = $this->chuliMsg($reply);
		$msgid = rand(5000000, 5999999);
		if ($is_group_msg) {
			$request = WqCommon::getSendGroupMsgRequest($rows, $from_uin, $reply, $msgid);
		} else {
			$request = WqCommon::getSendBuddyMsgRequest($rows, $from_uin, $reply, $msgid);
		}
		$get = WqCommon::web_curl($request, $rows['cookie'], false);
		$rerow = json_decode($get, true);
		if (@array_key_exists('retcode', $rerow) && $rerow['retcode'] == 0) {
			$this->runlogPer->insertMe($this->uin, "回复成功:" . $reply);
		} else {
			$this->runlogPer->insertMe($this->uin, "回复失败:" . $reply);
		}
	}

	/**
	 * 获取群成员信息，当没有记录时自动新增记录
	 */
	public function setGroupMember($rows, $group_uin, $member_uin, $send_uin) {
		$webGroup = $this->groupmemberPer->getMe($this->uin, $group_uin, $member_uin);
		if (!$webGroup) {
			$nick_name = WqCommon::getStrangerInfoBySendUin($send_uin, $rows);
			$this->groupmemberPer->insertMe($this->uin, $group_uin, $member_uin, $nick_name);
			$webGroup = $this->groupmemberPer->getMe($this->uin, $group_uin, $member_uin);
			$this->runlogPer->insertMe($this->uin, "新增群成员" . $member_uin);
		}
		return $webGroup;
	}

	/**
	 * 运行插件main方法
	 * @param string $plugin_class_name
	 * @param string $msg
	 * @param array $webGroup
	 * @return string 插件返回的字符
	 */
	public function runPluginMain($plugin_class_name, $msg, $webGroup) {
		$this->runlogPer->insertMe($this->uin, $plugin_class_name);
		$pluginHandler = null;
		eval("@\$pluginHandler = new " . $plugin_class_name . "();");
		if ($pluginHandler == null) return ReplyUtil::noReply();
		$pluginHandler->init($this->uin, $msg, $webGroup, $this->qqPer, $this->runlogPer, $this->groupmemberPer, $this->pluginPer);
		return $pluginHandler->main();
	}

}

?>